package com.zkhz.base.security.token;

import com.google.common.collect.Maps;
import com.zkhz.base.security.authentication.userdetails.model.SecurityUserDetails;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.SpringSecurityMessageSource;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.oauth2.provider.token.UserAuthenticationConverter;
import org.springframework.util.StringUtils;

import java.util.Collections;
import java.util.Map;

/**
 * @Description jwt转换认证换用信息处理类
 *
 * @author wuzeqin
 * @date 2020/5/29
 **/
public class JwtUserAuthenticationConverter implements UserAuthenticationConverter {

    private static final Logger LOGGER = LoggerFactory.getLogger(JwtUserAuthenticationConverter.class);

    protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();

    private final UserDetailsService userDetailsService;

    public JwtUserAuthenticationConverter(UserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
    }

    @Override
    public Map<String, ?> convertUserAuthentication(Authentication userAuthentication) {
        Object principal = userAuthentication.getPrincipal();
        if (principal instanceof SecurityUserDetails) {
            Map<String, ?> userInfo = ((SecurityUserDetails) principal).getUserInfo();
            return Collections.unmodifiableMap(Maps.filterValues(userInfo, v -> !StringUtils.isEmpty(v)));
        }
        return Collections.emptyMap();
    }

    @Override
    public Authentication extractAuthentication(Map<String, ?> map) {
        UserDetails userDetails = userDetailsService.loadUserByUsername((String) map.get("username"));
        UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, "N/A", userDetails.getAuthorities());
        authentication.eraseCredentials();
        return authentication;
    }


}
